/*
 * 代号：凤凰
 * http://www.jphenix.org
 * 2018年5月2日
 * V4.0
 */
package com.jphenix.driver.dbshell;

import com.jphenix.standard.docs.ClassInfo;

import java.sql.*;
import java.util.ArrayList;
import java.util.List;

/**
 * 允许底层数据处理事件类的事务处理类实例（壳）
 * @author MBG
 */
@ClassInfo({"2017-04-25 16:38","允许底层数据处理事件类的事务处理类实例（壳）"})
public class StatementImpl implements Statement {
    
    protected String          source       = null; //数据源主键
    protected ConnectionImpl  conn         = null; //连接类实例
    private   Statement       kernel       = null; //核心事务类
    protected EventVO         eVO          = null; //底层数据处理事件类实例容器
    
    private List<String>      batchSqlList = null; //批量处理语句序列
    
    /**
     * 构造函数
     * @param source 数据源主键
     * @param conn   连接类实例
     * @param kernel 核心事务类
     * @param eVO    底层数据处理事件类实例容器
     */
    public StatementImpl(String source,ConnectionImpl conn,Statement kernel,EventVO eVO) {
        super();
        this.source  = source;
        this.conn    = conn;
        this.kernel  = kernel;
        this.eVO     = eVO;
    }
    
    /**
     * 返回有效的批量处理语句序列
     * @return 批量处理语句序列
     */
    private List<String> getBatchSqlList(){
        if(batchSqlList==null) {
            batchSqlList = new ArrayList<String>();
        }
        return batchSqlList;
    }

    /**
     * 覆盖方法
     */
    @Override
    public <T> T unwrap(Class<T> iface) throws SQLException {
        return kernel.unwrap(iface);
    }

    /**
     * 覆盖方法
     */
    @Override
    public boolean isWrapperFor(Class<?> iface) throws SQLException {
        return kernel.isWrapperFor(iface);
    }

    /**
     * 覆盖方法
     */
    @Override
    public ResultSet executeQuery(String sql) throws SQLException {
        //触发执行前事件
        Object eObj = eVO.beforeExecute(source,sql,0,null,this);
        ResultSet res = kernel.executeQuery(sql);
        if(conn.autoCommit) {
        	eVO.afterExecute(source,eObj,true,-1);
        }else {
        	conn.dealInfoVec.add(new AfterDataVO(source,eObj,true,-1));
        }
        return res;
    }

    /**
     * 覆盖方法
     */
    @Override
    public int executeUpdate(String sql) throws SQLException {
        //触发执行前事件
        Object eObj = eVO.beforeExecute(source,sql,0,null,this);
        int res = kernel.executeUpdate(sql);
        if(conn.autoCommit) {
        	eVO.afterExecute(source,eObj,true,res);
        }else {
        	conn.dealInfoVec.add(new AfterDataVO(source,eObj,true,res));
        }
        return res;
    }

    /**
     * 覆盖方法
     */
    @Override
    public void close() throws SQLException {
        kernel.close();
    }

    /**
     * 覆盖方法
     */
    @Override
    public int getMaxFieldSize() throws SQLException {
        return kernel.getMaxFieldSize();
    }

    /**
     * 覆盖方法
     */
    @Override
    public void setMaxFieldSize(int max) throws SQLException {
        kernel.setMaxFieldSize(max);
    }

    /**
     * 覆盖方法
     */
    @Override
    public int getMaxRows() throws SQLException {
        return kernel.getMaxRows();
    }

    /**
     * 覆盖方法
     */
    @Override
    public void setMaxRows(int max) throws SQLException {
        kernel.setMaxRows(max);
    }

    /**
     * 覆盖方法
     */
    @Override
    public void setEscapeProcessing(boolean enable) throws SQLException {
        kernel.setEscapeProcessing(enable);
    }

    /**
     * 覆盖方法
     */
    @Override
    public int getQueryTimeout() throws SQLException {
        return kernel.getQueryTimeout();
    }

    /**
     * 覆盖方法
     */
    @Override
    public void setQueryTimeout(int seconds) throws SQLException {
        kernel.setQueryTimeout(seconds);
    }

    /**
     * 覆盖方法
     */
    @Override
    public void cancel() throws SQLException {
        kernel.cancel();
    }

    /**
     * 覆盖方法
     */
    @Override
    public SQLWarning getWarnings() throws SQLException {
        return kernel.getWarnings();
    }

    /**
     * 覆盖方法
     */
    @Override
    public void clearWarnings() throws SQLException {
        kernel.clearWarnings();
    }

    /**
     * 覆盖方法
     */
    @Override
    public void setCursorName(String name) throws SQLException {
        kernel.setCursorName(name);
    }

    /**
     * 覆盖方法
     */
    @Override
    public boolean execute(String sql) throws SQLException {
        //触发执行前事件
        Object eObj = eVO.beforeExecute(source,sql,0,null,this);
        boolean res = kernel.execute(sql);
        if(conn.autoCommit) {
        	eVO.afterExecute(source,eObj,res,-1);
        }else {
        	conn.dealInfoVec.add(new AfterDataVO(source,eObj,res,-1));
        }
        return res;
    }

    /**
     * 覆盖方法
     */
    @Override
    public ResultSet getResultSet() throws SQLException {
        return kernel.getResultSet();
    }

    /**
     * 覆盖方法
     */
    @Override
    public int getUpdateCount() throws SQLException {
        return kernel.getUpdateCount();
    }

    /**
     * 覆盖方法
     */
    @Override
    public boolean getMoreResults() throws SQLException {
        return kernel.getMoreResults();
    }

    /**
     * 覆盖方法
     */
    @Override
    public void setFetchDirection(int direction) throws SQLException {
        kernel.setFetchDirection(direction);
    }

    /**
     * 覆盖方法
     */
    @Override
    public int getFetchDirection() throws SQLException {
        return kernel.getFetchDirection();
    }

    /**
     * 覆盖方法
     */
    @Override
    public void setFetchSize(int rows) throws SQLException {
        kernel.setFetchSize(rows);
    }

    /**
     * 覆盖方法
     */
    @Override
    public int getFetchSize() throws SQLException {
        return kernel.getFetchSize();
    }

    /**
     * 覆盖方法
     */
    @Override
    public int getResultSetConcurrency() throws SQLException {
        return kernel.getResultSetConcurrency();
    }

    /**
     * 覆盖方法
     */
    @Override
    public int getResultSetType() throws SQLException {
        return kernel.getResultSetType();
    }

    /**
     * 覆盖方法
     */
    @Override
    public void addBatch(String sql) throws SQLException {
        getBatchSqlList().add(sql);
        kernel.addBatch(sql);
    }

    /**
     * 覆盖方法
     */
    @Override
    public void clearBatch() throws SQLException {
        kernel.clearBatch();
    }

    /**
     * 覆盖方法
     */
    @Override
    public int[] executeBatch() throws SQLException {
        //触发执行前事件
        Object eObj = eVO.beforeExecute(source,getBatchSqlList(),this);
        int[] res = kernel.executeBatch();
        int count = 0; //汇总影响数量
        for(int i=0;i<res.length;i++) {
        	count += res[i];
        }
        if(conn.autoCommit) {
        	eVO.afterExecute(source,eObj,true,count);
        }else {
        	conn.dealInfoVec.add(new AfterDataVO(source,eObj,true,count));
        }
        return res;
    }

    /**
     * 覆盖方法
     */
    @Override
    public Connection getConnection() throws SQLException {
        return conn;
    }

    /**
     * 覆盖方法
     */
    @Override
    public boolean getMoreResults(int current) throws SQLException {
        return kernel.getMoreResults(current);
    }

    /**
     * 覆盖方法
     */
    @Override
    public ResultSet getGeneratedKeys() throws SQLException {
        return kernel.getGeneratedKeys();
    }

    /**
     * 覆盖方法
     */
    @Override
    public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException {
        //触发执行前事件
        Object eObj = eVO.beforeExecute(source,sql,0,null,this);
        int res = kernel.executeUpdate(sql,autoGeneratedKeys);
        if(conn.autoCommit) {
        	eVO.afterExecute(source,eObj,true,res);
        }else {
        	conn.dealInfoVec.add(new AfterDataVO(source,eObj,true,res));
        }
        return res;
    }

    /**
     * 覆盖方法
     */
    @Override
    public int executeUpdate(String sql, int[] columnIndexes) throws SQLException {
        //触发执行前事件
        Object eObj = eVO.beforeExecute(source,sql,0,null,this);
        int res = kernel.executeUpdate(sql,columnIndexes);
        if(conn.autoCommit) {
        	eVO.afterExecute(source,eObj,true,res);
        }else {
        	conn.dealInfoVec.add(new AfterDataVO(source,eObj,true,res));
        }
        return res;
    }

    /**
     * 覆盖方法
     */
    @Override
    public int executeUpdate(String sql, String[] columnNames) throws SQLException {
        //触发执行前事件
        Object eObj = eVO.beforeExecute(source,sql,0,null,this);
        int res = kernel.executeUpdate(sql,columnNames);
        if(conn.autoCommit) {
        	eVO.afterExecute(source,eObj,true,res);
        }else {
        	conn.dealInfoVec.add(new AfterDataVO(source,eObj,true,res));
        }
        return res;
    }

    /**
     * 覆盖方法
     */
    @Override
    public boolean execute(String sql, int autoGeneratedKeys) throws SQLException {
        //触发执行前事件
        Object eObj = eVO.beforeExecute(source,sql,0,null,this);
        boolean res = kernel.execute(sql,autoGeneratedKeys);
        if(conn.autoCommit) {
        	eVO.afterExecute(source,eObj,res,-1);
        }else {
        	conn.dealInfoVec.add(new AfterDataVO(source,eObj,res,-1));
        	
        }
        return res;
    }

    /**
     * 覆盖方法
     */
    @Override
    public boolean execute(String sql, int[] columnIndexes) throws SQLException {
        //触发执行前事件
        Object eObj = eVO.beforeExecute(source,sql,0,null,this);
        boolean res = kernel.execute(sql,columnIndexes);
        if(conn.autoCommit) {
        	eVO.afterExecute(source,eObj,res,-1);
        }else {
        	conn.dealInfoVec.add(new AfterDataVO(source,eObj,res,-1));
        }
        return res;
    }

    /**
     * 覆盖方法
     */
    @Override
    public boolean execute(String sql, String[] columnNames) throws SQLException {
        //触发执行前事件
        Object eObj = eVO.beforeExecute(source,sql,0,null,this);
        boolean res = kernel.execute(sql,columnNames);
        if(conn.autoCommit) {
        	eVO.afterExecute(source,eObj,res,-1);
        }else {
        	conn.dealInfoVec.add(new AfterDataVO(source,eObj,res,-1));
        }
        return res;
    }

    /**
     * 覆盖方法
     */
    @Override
    public int getResultSetHoldability() throws SQLException {
        return kernel.getResultSetConcurrency();
    }

    /**
     * 覆盖方法
     */
    @Override
    public boolean isClosed() throws SQLException {
        return kernel.isClosed();
    }

    /**
     * 覆盖方法
     */
    @Override
    public void setPoolable(boolean poolable) throws SQLException {
        kernel.setPoolable(poolable);
    }

    /**
     * 覆盖方法
     */
    @Override
    public boolean isPoolable() throws SQLException {
        return kernel.isPoolable();
    }

	/**
	 * JDK1.7需要实现的方法
	 */
	@Override
    public void closeOnCompletion() throws SQLException {}

	/**
	 * JDK1.7需要实现的方法
	 */
	@Override
    public boolean isCloseOnCompletion() throws SQLException {
		return false;
	}
}
